#include "iuIPAddress.hpp"
#include <cstdio>
#include <cstring>
#include <arpa/inet.h>

/**
 * @brief Initialise l'adresse a 0.0.0.0
 */
iuIPAddress::iuIPAddress()
{
   m_address = 0;
}

/**
 * @brief Attribue l'adresse IP a partir d'un uint32_t (code dans la convention machine)
 * @param address l'adresse a attribuer
 */
void iuIPAddress::set(uint32_t address)
{
   m_address = address;
}

/**
 * @brief Recupere l'adresse IP sous la forme d'un uint32_t (code dans la convention machine)
 * @return Renvoie l'adresse IP sous la forme d'un uint32_t
 */
uint32_t iuIPAddress::get() const
{
   return m_address;
}

/**
 * @brief Teste si les deux adresses IP sont egales
 * @param addr la deuxieme adresse IP a comparer
 * @return Renvoie true si les deux adresses IP sont egales, false sinon
 */
bool iuIPAddress::operator==(const iuIPAddress &addr) const
{
   return (m_address == addr.m_address);
}

/**
 * @brief Lit l'adresse IP a partir d'un buffer (d'au moins 4 octets)
 * @param buffer l'adresse du debut du buffer
 * @return Renvoie le nombre d'octets lus (ici, 4)
 */
uint16_t iuIPAddress::fromBuffer(const char *buffer)
{
   memcpy(&m_address, buffer, 4);
   m_address = ntohl(m_address);

   return 4;
}

/**
 * @brief Ecrit l'adresse IP dans un buffer (d'au moins 4 octets)
 * @param buffer l'adresse du debut du buffer
 * @return Renvoie le nombre d'octets ecrits dans le buffer (ici, 4)
 */
uint16_t iuIPAddress::toBuffer(char *buffer) const
{
   uint32_t tmp;

   tmp = htonl(m_address);
   memcpy(buffer, &tmp, 4);

   return 4;
}

/**
 * @brief Convertit une chaine de caracteres de la forme 192.168.0.1 en l'adresse IP
 * @param string la chaine de caracteres a convertir
 * @return Renvoie true si la conversion s'est deroulee correctement, false sinon
 */
bool iuIPAddress::fromString(const char *string)
{
   int addr1, addr2, addr3, addr4;

   if (sscanf(string, "%d.%d.%d.%d", &addr1, &addr2, &addr3, &addr4) != 4)
      return false;
   if (addr1 > 0xff || addr2 > 0xff || addr3 > 0xff || addr4 > 0xff)
      return false;

   m_address = (addr1 << 24) | (addr2 << 16) | (addr3 << 8) | (addr4);
   return true;
}

/**
 * @brief Convertit l'adresse IP en chaine de caracteres de la forme 192.168.0.1
 * @return Renvoie la chaine de caracteres (allouee statiquement)
 */
char *iuIPAddress::toString() const
{
   static char str[32];

   sprintf(str, "%d.%d.%d.%d", (m_address & 0xff000000) >> 24,
         (m_address & 0x00ff0000) >> 16, (m_address & 0x0000ff00) >> 8, (m_address & 0x000000ff));
   return str;
}
